package com.dd.admin.controller.file;

import cn.dev33.satoken.annotation.SaIgnore;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.dd.common.dto.system.file.SysFileQueryDTO;
import com.dd.common.dto.system.file.SysFileUpdateDTO;
import com.dd.common.entity.SysFile;
import com.dd.common.enums.ErrorEnum;
import com.dd.common.exception.BusinessException;
import com.dd.common.pojo.dto.FileUploadDTO;
import com.dd.common.pojo.dto.IdsDTO;
import com.dd.common.pojo.dto.PageDTO;
import com.dd.common.pojo.vo.UploadFilesVo;
import com.dd.common.service.SysFileService;
import com.dd.common.utils.AjaxResult;
import com.dd.common.utils.PageResult;
import com.dd.common.validator.annotation.IDMust;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.constraints.NotBlank;


/**
 * @author cheng
 */
@SaIgnore
@Validated
@Slf4j
@Tag(name = "文件管理", description = "文件管理接口")
@RestController
@RequestMapping("/file")
public class FileController {

    @Resource
    private SysFileService sysFileService;

    /**
     * 上传文件
     * consumes 指定该方法只处理特定Content-Type的请求
     */
    @Operation(summary = "文件上传", requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(
            required = true,
            content = @Content(mediaType = MediaType.MULTIPART_FORM_DATA_VALUE, schema = @Schema(implementation = FileUploadDTO.class))
    ))
    @PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public AjaxResult<UploadFilesVo> uploadFile(@Validated FileUploadDTO dto) {
        return AjaxResult.success(sysFileService.uploadFile(dto.getFile(), dto));
    }

    @Operation(summary = "文件上传检查", description = "hash检查文件是否已经存在，true表示已存在")
    @GetMapping("/check")
    public AjaxResult<Boolean> checkFile(@NotBlank(message = "hash不能为空") String hash) {
        return AjaxResult.success(sysFileService.checkFile(hash) != null);
    }

    @Operation(summary = "文件列表")
    @GetMapping("/list")
    public AjaxResult<Object> list(@Validated SysFileQueryDTO dto) {
        LambdaQueryWrapper<SysFile> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(StringUtils.hasText(dto.getFileName()), SysFile::getFileName, dto.getFileName())
                .like(StringUtils.hasText(dto.getMimeType()), SysFile::getMimeType, dto.getMimeType())
                .like(StringUtils.hasText(dto.getFilePath()), SysFile::getFilePath, dto.getFilePath())
                .eq(dto.getBizId() != null, SysFile::getBizId, dto.getBizId())
                .eq(dto.getUploadUserId() != null, SysFile::getUploadUserId, dto.getUploadUserId())
                .eq(dto.getType() != null, SysFile::getType, dto.getType())
                .ge(dto.getCreatedAtStart() != null, SysFile::getCreateTime, dto.getCreatedAtStart())
                .le(dto.getCreatedAtEnd() != null, SysFile::getCreateTime, dto.getCreatedAtEnd())
                .ge(dto.getUpdatedAtStart() != null, SysFile::getUpdateTime, dto.getUpdatedAtStart())
                .le(dto.getUpdatedAtEnd() != null, SysFile::getUpdateTime, dto.getUpdatedAtEnd())
                .orderByAsc(SysFile::getCreateTime);
        return AjaxResult.success(sysFileService.list(queryWrapper));
    }

    @Operation(summary = "文件分页列表")
    @GetMapping("/page")
    public AjaxResult<Object> page(@Validated PageDTO pageDTO, @Validated SysFileQueryDTO dto) {
        Page<SysFile> page = Page.of(pageDTO.getCurrent(), pageDTO.getSize());
        LambdaQueryWrapper<SysFile> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(StringUtils.hasText(dto.getFileName()), SysFile::getFileName, dto.getFileName())
                .like(StringUtils.hasText(dto.getMimeType()), SysFile::getMimeType, dto.getMimeType())
                .like(StringUtils.hasText(dto.getFilePath()), SysFile::getFilePath, dto.getFilePath())
                .eq(dto.getBizId() != null, SysFile::getBizId, dto.getBizId())
                .eq(dto.getUploadUserId() != null, SysFile::getUploadUserId, dto.getUploadUserId())
                .eq(dto.getType() != null, SysFile::getType, dto.getType())
                .ge(dto.getCreatedAtStart() != null, SysFile::getCreateTime, dto.getCreatedAtStart())
                .le(dto.getCreatedAtEnd() != null, SysFile::getCreateTime, dto.getCreatedAtEnd())
                .ge(dto.getUpdatedAtStart() != null, SysFile::getUpdateTime, dto.getUpdatedAtStart())
                .le(dto.getUpdatedAtEnd() != null, SysFile::getUpdateTime, dto.getUpdatedAtEnd())
                .orderByAsc(SysFile::getCreateTime);
        IPage<SysFile> result = sysFileService.page(page, queryWrapper);
        return AjaxResult.success(PageResult.iPageHandle(result.getTotal(), result.getCurrent(), result.getSize(), result.getRecords()));
    }

    @Operation(summary = "文件编辑")
    @PatchMapping("/edit")
    public AjaxResult<Boolean> edit(@Validated @RequestBody SysFileUpdateDTO dto) {
        SysFile existingFile = sysFileService.getById(dto.getId());
        if (existingFile == null) {
            throw new BusinessException(ErrorEnum.DATA_NOT_FOUND, "文件不存在");
        }
        LambdaUpdateWrapper<SysFile> updateWrapper = new LambdaUpdateWrapper<SysFile>()
                .eq(SysFile::getId, dto.getId())
                .set(dto.getOriginalFileName() != null, SysFile::getOriginalName, dto.getOriginalFileName());
        return AjaxResult.success(sysFileService.update(null, updateWrapper));
    }

    @Operation(summary = "文件批量删除")
    @PostMapping("/delete/batch")
    public AjaxResult<Boolean> deleteBatch(@Validated @RequestBody IdsDTO dto) {
        return AjaxResult.success(sysFileService.removeBatchByIds(dto.getIds()));
    }
    @Operation(summary = "文件批量移动", parameters = @Parameter(name = "folderId", in = ParameterIn.PATH, description = "文件夹ID"))
    @PostMapping("/move/batch/{folderId}")
    public AjaxResult<Boolean> moveBatch(@PathVariable @IDMust Long folderId, @Validated @RequestBody IdsDTO dto) {
        return AjaxResult.success(sysFileService.moveBatch(folderId, dto.getIds()));
    }
}
